
/////////////////////////////////////////////////////////////////////
//  This file is a part of "GFunction.h", not a stand-alone file.
//	Do NOT directly include this file, just include "GFunction.h".
/////////////////////////////////////////////////////////////////////

namespace CALLERNS
{
	//-----------------------------------------------------
	// 16 params
	template<typename TRET, 
		typename P1 = void, typename P2 = void, typename P3 = void, typename P4 = void,
		typename P5 = void, typename P6 = void, typename P7 = void, typename P8 = void,
		typename P9 = void, typename P10= void, typename P11= void, typename P12= void,
		typename P13= void, typename P14= void, typename P15= void, typename P16= void>
	struct Caller
	{	
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
		{
			U8* frame = stk.CurrentFrame();
			*(Returnval<TRET>::Read(reg, frame)) = (*((TRET(CALLCONV **)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
				Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
				Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
				Parameter<P11>::Read(reg, frame),Parameter<P12>::Read(reg, frame),
				Parameter<P13>::Read(reg, frame),Parameter<P14>::Read(reg, frame),
				Parameter<P15>::Read(reg, frame),Parameter<P16>::Read(reg, frame));
			return;
		}
	};
	// no return value
	template<
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9, typename P10,typename P11,typename P12,typename P13,typename P14,typename P15,typename P16> 
	struct Caller<void, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			(*((void(CALLCONV **)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
				Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
				Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
				Parameter<P11>::Read(reg, frame),Parameter<P12>::Read(reg, frame),
				Parameter<P13>::Read(reg, frame),Parameter<P14>::Read(reg, frame),
				Parameter<P15>::Read(reg, frame),Parameter<P16>::Read(reg, frame));
			return;
		}
	};
	//-----------------------------------------------------
	// 15 params
	template<typename TRET, 
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9, typename P10,typename P11,typename P12,typename P13,typename P14,typename P15> 
	struct Caller<TRET, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			*(Returnval<TRET>::Read(reg, frame)) = (*((TRET(CALLCONV **)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
				Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
				Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
				Parameter<P11>::Read(reg, frame),Parameter<P12>::Read(reg, frame),
				Parameter<P13>::Read(reg, frame),Parameter<P14>::Read(reg, frame),
				Parameter<P15>::Read(reg, frame));
			return;
		}
	};
	// no return value
	template<
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9, typename P10,typename P11,typename P12,typename P13,typename P14,typename P15> 
	struct Caller<void, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			(*((void(CALLCONV **)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
				Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
				Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
				Parameter<P11>::Read(reg, frame),Parameter<P12>::Read(reg, frame),
				Parameter<P13>::Read(reg, frame),Parameter<P14>::Read(reg, frame),
				Parameter<P15>::Read(reg, frame));
			return;
		}
	};
	//-----------------------------------------------------
	// 14 params
	template<typename TRET, 
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9, typename P10,typename P11,typename P12,typename P13,typename P14> 
	struct Caller<TRET, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			*(Returnval<TRET>::Read(reg, frame)) = (*((TRET(CALLCONV **)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
				Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
				Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
				Parameter<P11>::Read(reg, frame),Parameter<P12>::Read(reg, frame),
				Parameter<P13>::Read(reg, frame),Parameter<P14>::Read(reg, frame));
			return;
		}
	};
	// no return value
	template<
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9, typename P10,typename P11,typename P12,typename P13,typename P14> 
	struct Caller<void, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			(*((void(CALLCONV **)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
				Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
				Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
				Parameter<P11>::Read(reg, frame),Parameter<P12>::Read(reg, frame),
				Parameter<P13>::Read(reg, frame),Parameter<P14>::Read(reg, frame));
			return;
		}
	};
	//-----------------------------------------------------
	// 13 params
	template<typename TRET, 
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9, typename P10,typename P11,typename P12,typename P13> 
	struct Caller<TRET, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			*(Returnval<TRET>::Read(reg, frame)) = (*((TRET(CALLCONV **)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
				Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
				Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
				Parameter<P11>::Read(reg, frame),Parameter<P12>::Read(reg, frame),
				Parameter<P13>::Read(reg, frame));	
			return;
		}
	};
	// no return value
	template<
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9, typename P10,typename P11,typename P12,typename P13> 
	struct Caller<void, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg) 
		{
			U8* frame = stk.CurrentFrame();
			(*((void(CALLCONV **)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
				Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
				Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
				Parameter<P11>::Read(reg, frame),Parameter<P12>::Read(reg, frame),
				Parameter<P13>::Read(reg, frame));	
			return;
		}
	};
	//-----------------------------------------------------
	// 12 params
	template<typename TRET, 
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9, typename P10,typename P11,typename P12>
	struct Caller<TRET, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			*(Returnval<TRET>::Read(reg, frame)) = (*((TRET(CALLCONV **)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
				Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
				Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
				Parameter<P11>::Read(reg, frame),Parameter<P12>::Read(reg, frame));
			return;
		}
	};
	// no return value
	template<
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9, typename P10,typename P11,typename P12> 
	struct Caller<void, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			(*((void(CALLCONV **)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
				Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
				Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
				Parameter<P11>::Read(reg, frame),Parameter<P12>::Read(reg, frame));
			return;
		}
	};
	//-----------------------------------------------------
	// 11 params
	template<typename TRET, 
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9, typename P10,typename P11> 
	struct Caller<TRET, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			*(Returnval<TRET>::Read(reg, frame)) = (*((TRET(CALLCONV **)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
				Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
				Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
				Parameter<P11>::Read(reg, frame));
			return;
		}
	};
	// no return value
	template<
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9, typename P10,typename P11> 
	struct Caller<void, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			(*((void(CALLCONV **)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
				Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
				Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame),
				Parameter<P11>::Read(reg, frame));
			return;
		}
	};
	//-----------------------------------------------------
	// 10 params
	template<typename TRET, 
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9, typename P10> 
	struct Caller<TRET, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			*(Returnval<TRET>::Read(reg, frame)) 
				= (*((TRET(CALLCONV **)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
				Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
				Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame));
			return;
		}
	};
	// no return value
	template<
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9, typename P10> 
	struct Caller<void, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			(*((void(CALLCONV **)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
				Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
				Parameter<P9>::Read(reg, frame), Parameter<P10>::Read(reg, frame));
			return;
		}
	};
	//-----------------------------------------------------
	// 9 params
	template<typename TRET,
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9> 
	struct Caller<TRET, P1, P2, P3, P4, P5, P6, P7, P8, P9, void, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			*(Returnval<TRET>::Read(reg, frame)) = (*((TRET(CALLCONV **)(P1, P2, P3, P4, P5, P6, P7, P8, P95))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
				Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
				Parameter<P9>::Read(reg, frame));
			return;
		}
	};
	// no return value
	template<
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
		typename P9> 
	struct Caller<void, P1, P2, P3, P4, P5, P6, P7, P8, P9, void, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			(*((void(CALLCONV **)(P1, P2, P3, P4, P5, P6, P7, P8, P9))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
				Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame),
				Parameter<P9>::Read(reg, frame));
			return;
		}
	};
	//-----------------------------------------------------
	// 8 params
	template<typename TRET,
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8> 
	struct Caller<TRET, P1, P2, P3, P4, P5, P6, P7, P8, void, void, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			*(Returnval<TRET>::Read(reg, frame)) = (*((TRET(CALLCONV **)(P1, P2, P3, P4, P5, P6, P7, P8))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
				Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame));
			return;
		}
	};
	// no return value
	template<
		typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8> 
	struct Caller<void, P1, P2, P3, P4, P5, P6, P7, P8, void, void, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			(*((void(CALLCONV **)(P1, P2, P3, P4, P5, P6, P7, P8))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
				Parameter<P7>::Read(reg, frame), Parameter<P8>::Read(reg, frame));
			return;
		}
	};
	//-----------------------------------------------------
	// 7 params
	template<typename TRET, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7> 
	struct Caller<TRET, P1, P2, P3, P4, P5, P6, P7, void, void, void, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			*(Returnval<TRET>::Read(reg, frame)) = (*((TRET(CALLCONV **)(P1, P2, P3, P4, P5, P6, P7))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
				Parameter<P7>::Read(reg, frame));
			return;
		}
	};
	// no return value
	template<typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
	struct Caller<void, P1, P2, P3, P4, P5, P6, P7, void, void, void, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			(*((void(CALLCONV **)(P1, P2, P3, P4, P5, P6, P7))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame),
				Parameter<P7>::Read(reg, frame));
			return;
		}
	};
	//-----------------------------------------------------
	// 6 params
	template<typename TRET, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
	struct Caller<TRET, P1, P2, P3, P4, P5, P6, void, void, void, void, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			*(Returnval<TRET>::Read(reg, frame)) = (*((TRET(CALLCONV **)(P1, P2, P3, P4, P5, P6))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame));
			return;
		}
	};
	// no return value
	template<typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
	struct Caller<void, P1, P2, P3, P4, P5, P6, void, void, void, void, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			(*((void(CALLCONV **)(P1, P2, P3, P4, P5, P6))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame), Parameter<P6>::Read(reg, frame));
			return;
		}
	};
	//-----------------------------------------------------
	// 5 params
	template<typename TRET, typename P1, typename P2, typename P3, typename P4, typename P5> 
	struct Caller<TRET, P1, P2, P3, P4, P5, void, void, void, void, void, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			*(Returnval<TRET>::Read(reg, frame)) = (*((TRET(CALLCONV **)(P1, P2, P3, P4, P5))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame));
			return;
		}
	};
	// no return value
	template<typename P1, typename P2, typename P3, typename P4, typename P5>
	struct Caller<void, P1, P2, P3, P4, P5, void, void, void, void, void, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			(*((void(CALLCONV **)(P1, P2, P3, P4, P5))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame),
				Parameter<P5>::Read(reg, frame));
			return;
		}
	};
	//-----------------------------------------------------
	// 4 params
	template<typename TRET, typename P1, typename P2, typename P3, typename P4>
	struct Caller<TRET, P1, P2, P3, P4, void, void, void, void, void, void, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			*(Returnval<TRET>::Read(reg, frame)) = (*((TRET(CALLCONV **)(P1, P2, P3, P4))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame));
			return;
		}
	};
	// no return value
	template<typename P1, typename P2, typename P3, typename P4>
	struct Caller<void, P1, P2, P3, P4, void, void, void, void, void, void, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			(*((void(CALLCONV **)(P1, P2, P3, P4))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame), Parameter<P4>::Read(reg, frame));
			return;
		}
	};
	//-----------------------------------------------------
	// 3 params
	template<typename TRET, typename P1, typename P2, typename P3>
	struct Caller<TRET, P1, P2, P3, void, void, void, void, void, void, void, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			*(Returnval<TRET>::Read(reg, frame)) = (*((TRET(CALLCONV **)(P1, P2, P3))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame));
			return;
		}
	};
	// no return value
	template<typename P1, typename P2, typename P3>
	struct Caller<void, P1, P2, P3, void, void, void, void, void, void, void, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			(*((void(CALLCONV **)(P1, P2, P3))&callee))(
				Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame),
				Parameter<P3>::Read(reg, frame));
			return;
		}
	};
	//-----------------------------------------------------
	// 2 params
	template<typename TRET, typename P1, typename P2>
	struct Caller<TRET, P1, P2, void, void, void, void, void, void, void, void, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			*(Returnval<TRET>::Read(reg, frame)) = (*((TRET(CALLCONV **)(P1, P2))&callee))(Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame));
			return;
		}
	};
	// no return value
	template<typename P1, typename P2> 
	struct Caller<void, P1, P2, void, void, void, void, void, void, void, void, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			(*((void(CALLCONV **)(P1, P2))&callee))(Parameter<P1>::Read(reg, frame), Parameter<P2>::Read(reg, frame));
			return;
		}
	};
	//-----------------------------------------------------
	// 1 params
	template<typename TRET, typename P1> 
	struct Caller<TRET, P1, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			*(Returnval<TRET>::Read(reg, frame)) = (*((TRET(CALLCONV **)(P1))&callee))(Parameter<P1>::Read(reg, frame));
			return;
		}
	};
	// no return value
	template<typename P1> 
	struct Caller<void, P1, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			(*((void(CALLCONV **)(P1))&callee))(Parameter<P1>::Read(reg, frame));
			return;
		}
	};

	//-----------------------------------------------------
	// no param
	template<typename TRET> 
	struct Caller<TRET, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker& stk, GRegister& reg)
		{
			U8* frame = stk.CurrentFrame();
			*(Returnval<TRET>::Read(reg, frame)) = (*((TRET(CALLCONV **)())&callee))();
			return;
		}
	};
	// no return value
	template<> 
	struct Caller<void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void, void>
	{
		static inline void Invoke(void * callee, GStacker&, GRegister&)
		{
			(*((void(CALLCONV **)())&callee))();
			return;
		}
	};
	//-----------------------------------------------------
}

/////////////////////////////////////////////////////////////////////
// Template: ExportFunction, for global functions, which have a return value.
// Return: FunctionObject
/////////////////////////////////////////////////////////////////////
template<typename TRET, 
	typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
	typename P9, typename P10,typename P11,typename P12,typename P13,typename P14,typename P15,typename P16>
inline FunctionObject ExportFunction(TRET(CALLCONV * f)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16))
{
	return FunctionObject(CALLERNS::Caller<TRET, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15, P16>::Invoke, *(void**)&f);
}

template<typename TRET, 
	typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
	typename P9, typename P10,typename P11,typename P12,typename P13,typename P14,typename P15>
inline FunctionObject ExportFunction(TRET(CALLCONV * f)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15))
{
	return FunctionObject(CALLERNS::Caller<TRET, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14, P15>::Invoke, *(void**)&f);
}

template<typename TRET, 
	typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
	typename P9, typename P10,typename P11,typename P12,typename P13,typename P14>
inline FunctionObject ExportFunction(TRET(CALLCONV * f)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14))
{
	return FunctionObject(CALLERNS::Caller<TRET, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13, P14>::Invoke, *(void**)&f);
}

template<typename TRET, 
	typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
	typename P9, typename P10,typename P11,typename P12,typename P13>
inline FunctionObject ExportFunction(TRET(CALLCONV * f)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13))
{
	return FunctionObject(CALLERNS::Caller<TRET, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12, P13>::Invoke, *(void**)&f);
}

template<typename TRET, 
	typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
	typename P9, typename P10,typename P11,typename P12> 
inline FunctionObject ExportFunction(TRET(CALLCONV * f)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12))
{
	return FunctionObject(CALLERNS::Caller<TRET, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11, P12>::Invoke, *(void**)&f);
}

template<typename TRET, 
	typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
	typename P9, typename P10,typename P11> 
inline FunctionObject ExportFunction(TRET(CALLCONV * f)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11))
{
	return FunctionObject(CALLERNS::Caller<TRET, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10, P11>::Invoke, *(void**)&f);
}

template<typename TRET, 
	typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
	typename P9, typename P10> 
inline FunctionObject ExportFunction(TRET(CALLCONV * f)(P1, P2, P3, P4, P5, P6, P7, P8, P9, P10))
{
	return FunctionObject(CALLERNS::Caller<TRET, P1, P2, P3, P4, P5, P6, P7, P8, P9, P10>::Invoke, *(void**)&f);
}

template<typename TRET, 
	typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8,
	typename P9> 
inline FunctionObject ExportFunction(TRET(CALLCONV * f)(P1, P2, P3, P4, P5, P6, P7, P8, P9))
{
	return FunctionObject(CALLERNS::Caller<TRET, P1, P2, P3, P4, P5, P6, P7, P8, P9>::Invoke, *(void**)&f);
}

template<typename TRET, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7, typename P8>
inline FunctionObject ExportFunction(TRET(CALLCONV * f)(P1, P2, P3, P4, P5, P6, P7, P8)) 
{
	return FunctionObject(CALLERNS::Caller<TRET, P1, P2, P3, P4, P5, P6, P7, P8>::Invoke, *(void**)&f);
}

template<typename TRET, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6, typename P7>
inline FunctionObject ExportFunction(TRET(CALLCONV * f)(P1, P2, P3, P4, P5, P6, P7))
{ 
	return FunctionObject(CALLERNS::Caller<TRET, P1, P2, P3, P4, P5, P6, P7>::Invoke, *(void**)&f);
}

template<typename TRET, typename P1, typename P2, typename P3, typename P4, typename P5, typename P6>
inline FunctionObject ExportFunction(TRET(CALLCONV * f)(P1, P2, P3, P4, P5, P6)) 
{ 
	return FunctionObject(CALLERNS::Caller<TRET, P1, P2, P3, P4, P5, P6>::Invoke, *(void**)&f);
}

template<typename TRET, typename P1, typename P2, typename P3, typename P4, typename P5>
inline FunctionObject ExportFunction(TRET(CALLCONV * f)(P1, P2, P3, P4, P5))
{ 
	return FunctionObject(CALLERNS::Caller<TRET, P1, P2, P3, P4, P5>::Invoke, *(void**)&f);
}

template<typename TRET, typename P1, typename P2, typename P3, typename P4> 
inline FunctionObject ExportFunction(TRET(CALLCONV * f)(P1, P2, P3, P4)) 
{ 
	return FunctionObject(CALLERNS::Caller<TRET, P1, P2, P3, P4>::Invoke, *(void**)&f);
}

template<typename TRET, typename P1, typename P2, typename P3> 
inline FunctionObject ExportFunction(TRET(CALLCONV * f)(P1, P2, P3))
{ 
	return FunctionObject(CALLERNS::Caller<TRET, P1, P2, P3>::Invoke, *(void**)&f);
}

template<typename TRET, typename P1, typename P2> 
inline FunctionObject ExportFunction(TRET(CALLCONV * f)(P1, P2)) 
{ 
	return FunctionObject(CALLERNS::Caller<TRET, P1, P2>::Invoke, *(void**)&f);
}

template<typename TRET, typename P1> 
inline FunctionObject ExportFunction(TRET(CALLCONV * f)(P1))
{ 
	return FunctionObject(CALLERNS::Caller<TRET, P1>::Invoke, *(void**)&f);
}

template<typename TRET> 
inline FunctionObject ExportFunction(TRET(CALLCONV * f)(void)) 
{ 
	return FunctionObject(CALLERNS::Caller<TRET>::Invoke, *(void**)&f);
}

